home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / fsovl / main.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  11KB  |  458 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  MAIN.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. Prototype char *DevName;
  14. Prototype short DDebug;
  15.  
  16. void myexit(void);
  17.  
  18. char DevName[64] = { 4, "arch" };
  19. short DDebug;
  20.  
  21. const static char Ident[] = { "$VER: REGISTERED/COMMERCIAL FSOVL-HANDLER "
  22.   VERSION ".01R (" __COMMODORE_DATE__ ") "
  23.   "(c)Copyright 1992-93 Obvious Implementations Corp, Redistribution and use under DICE-LICENSE.TXT\n\r"
  24. };
  25.  
  26. void
  27. main(ac, av)
  28. short ac;
  29. char *av[];
  30. {
  31.     DosPacket  *packet;
  32.  
  33.     {
  34.     short i;
  35.  
  36.     for (i = 1; i < ac; ++i) {
  37.         char *ptr = av[i];
  38.  
  39.         if (*ptr != '-') {
  40.         makebstr(ptr, strlen(ptr), DevName);
  41.         continue;
  42.         }
  43.         ptr += 2;
  44.         switch(ptr[-1]) {
  45.         case 'd':
  46.         DDebug = (*ptr) ? strtol(ptr, NULL, 0) : 1;
  47.         break;
  48.         }
  49.     }
  50.     }
  51.     atexit(myexit);
  52.     dbprintf(("Device: %s:\n", DevName + 1));
  53.     Initialize(DevName);
  54.     InitCore();
  55.  
  56.     /*
  57.      *    Main Loop
  58.      */
  59.  
  60.     for (;;) {
  61.         long r;
  62.  
  63.     dbprintf(("LockRefs %d\n", LockRefs));
  64.     {
  65.         Message *msg;
  66.         long sigs;
  67.  
  68.         while ((msg = GetMsg(PktPort)) == NULL) {
  69.         sigs = Wait(PktPortMask | SIGBREAKF_CTRL_D);
  70.         if ((sigs & SIGBREAKF_CTRL_D) && LockRefs == 0)
  71.             exit(0);
  72.         }
  73.         packet = (DosPacket *)msg->mn_Node.ln_Name;
  74.     }
  75.  
  76.     r = -ERROR_OBJECT_NOT_FOUND;
  77.     packet->dp_Res1 = 0;
  78.     packet->dp_Res2 = 0;
  79.  
  80.     dbprintf(("packet %08lx (%d) %08lx %08lx %08lx %08lx\n", 
  81.         packet->dp_Type, packet->dp_Type,
  82.         packet->dp_Arg1,
  83.         packet->dp_Arg2,
  84.         packet->dp_Arg3,
  85.         packet->dp_Arg4
  86.     ));
  87.  
  88.     switch(packet->dp_Type) {
  89.     case ACTION_DIE:
  90.         break;
  91.     case ACTION_FINDUPDATE:     /*    FileHandle,Lock,Name        Bool*/
  92.     case ACTION_FINDINPUT:        /*    FileHandle,Lock,Name        Bool*/
  93.     case ACTION_FINDOUTPUT:     /*    FileHandle,Lock,Name        Bool*/
  94.         {
  95.         FileHandle *fh = BTOC(packet->dp_Arg1);
  96.         GEntry *gentry = BLockToGEntry(packet->dp_Arg2);
  97.         short nameLen;
  98.         char *name = BNameToPtr(packet->dp_Arg3, &nameLen);
  99.         GHandle *ghan = NULL;
  100.  
  101.         dbprintf(("open %.*s %d\n", nameLen, name, packet->dp_Type));
  102.  
  103.         if (gentry=MakeGEntry(gentry,name,nameLen,packet->dp_Type)) {
  104.             if (gentry->ge_Flags & GEF_DIRECTORY)
  105.             r = -ERROR_OBJECT_WRONG_TYPE;
  106.             else
  107.                 ghan = MakeGHandle(gentry, packet->dp_Type);
  108.         }
  109.         if (ghan) {
  110.             fh->fh_Arg1 = ghan;
  111.             fh->fh_Port = (MsgPort *)DOS_TRUE;
  112.             r = DOS_TRUE;
  113.             dbprintf(("Success, file size %d\n",gentry->ge_Bytes));
  114.         } else {
  115.             fh->fh_Port = (MsgPort *)DOS_FALSE;
  116.         }
  117.         if (gentry)
  118.             FreeGEntry(gentry, packet->dp_Type);
  119.         }
  120.         break;
  121.     case ACTION_END:        /*    FHArg1              Bool:TRUE*/
  122.         {
  123.         GHandle *ghan = (GHandle *)packet->dp_Arg1;
  124.  
  125.         FreeGHan(ghan);
  126.         r = 0;
  127.         }
  128.         break;
  129.     case ACTION_READ:        /*    FHArg1,CPTRBuffer,Length    ActLength*/
  130.         {
  131.         GHandle *ghan = (GHandle *)packet->dp_Arg1;
  132.         GEntry *gentry = ghan->gh_GEntry;
  133.         long n;
  134.  
  135.         n = ReadDataGEntry(
  136.             gentry, 
  137.             ghan->gh_Pos, 
  138.             (void *)packet->dp_Arg2,
  139.             packet->dp_Arg3
  140.         );
  141.         if (n > 0)
  142.             ghan->gh_Pos += n;
  143.         r = n;
  144.         }
  145.         break;
  146.     case ACTION_WRITE:        /*    FHArg1,CPTRBuffer,Length    ActLength*/
  147.         {
  148.         GHandle *ghan = (GHandle *)packet->dp_Arg1;
  149.         GEntry *gentry = ghan->gh_GEntry;
  150.         long n;
  151.  
  152.         n = WriteDataGEntry(
  153.             gentry,
  154.             ghan->gh_Pos,
  155.             (void *)packet->dp_Arg2,
  156.             packet->dp_Arg3
  157.         );
  158.         if (n > 0)
  159.             ghan->gh_Pos += n;
  160.         r = n;
  161.         }
  162.         break;
  163.     case ACTION_SEEK:    /*    FHArg1,Position,Mode        OldPosition */
  164.         {
  165.         GHandle *ghan = (GHandle *)packet->dp_Arg1;
  166.         GEntry *gentry = ghan->gh_GEntry;
  167.         long n = packet->dp_Arg2;
  168.  
  169.         switch(packet->dp_Arg3) {
  170.         case -1:    // relative to beginning
  171.             break;
  172.         case 0:        // relative to current
  173.             n += ghan->gh_Pos;
  174.             break;
  175.         case 1:        // relative to end
  176.             n += gentry->ge_Bytes;
  177.             break;
  178.         }
  179.         if (n < 0 || n > gentry->ge_Bytes) {
  180.             r = -ERROR_SEEK_ERROR;
  181.         } else {
  182.             r = ghan->gh_Pos;
  183.             ghan->gh_Pos = n;
  184.         }
  185.         }
  186.         break;
  187.     case ACTION_CREATE_DIR:     /*    Lock,Name            Lock    */
  188.         {
  189.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  190.         short nameLen;
  191.         char *name = BNameToPtr(packet->dp_Arg2, &nameLen);
  192.  
  193.         r = -ERROR_OBJECT_NOT_FOUND;
  194.         if (gentry = MakeGEntry(gentry,name,nameLen,1006)) {
  195.             if (gentry->ge_Parent && gentry->ge_Parent != &GRoot) {
  196.             r = CreateDirPacket(
  197.                 gentry->ge_Parent->ge_Lock,
  198.                 gentry->ge_Node.ln_Name + 1,
  199.                 (ubyte)gentry->ge_Node.ln_Name[0]
  200.             );
  201.             if (r > 0)
  202.                 UnLockPacket(r);
  203.             }
  204.             FreeGEntry(gentry, 1006);
  205.         }
  206.         if (r < 0)
  207.             break;
  208.         packet->dp_Arg3 = EXCLUSIVE_LOCK;
  209.         }
  210.         /* fall through */
  211.     case ACTION_LOCATE_OBJECT:  /*    Lock,Name,Mode            Lock    */
  212.         {
  213.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  214.         short nameLen;
  215.         char *name = BNameToPtr(packet->dp_Arg2, &nameLen);
  216.         long mode = packet->dp_Arg3;
  217.  
  218.         if (gentry = MakeGEntry(gentry, name, nameLen, mode)) {
  219.             FileLock *flock = MakeDosFileLock(gentry, mode);
  220.             r = CTOB(flock);
  221.         } else {
  222.             r = -ERROR_OBJECT_NOT_FOUND;
  223.         }
  224.         }
  225.         break;
  226.     case ACTION_RENAME_DISK:    /*    Name                Bool    */
  227.         {
  228.         r = 0;
  229.         }
  230.         break;
  231.     case ACTION_FREE_LOCK:        /*    Lock                Bool    */
  232.         {
  233.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  234.         FileLock *flock = BTOC(packet->dp_Arg1);
  235.         long mode = flock->fl_Access;
  236.  
  237.         FreeGEntry(gentry, mode);
  238.         FreeDosFileLock(flock);
  239.         r = 0;
  240.         }
  241.         break;
  242.     case ACTION_COPY_DIR:        /*    Lock                Lock    */
  243.         {
  244.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  245.         FileLock *flock = MakeDosFileLock(gentry, 1005);
  246.         MakeGEntry(gentry, "", 0, 1005);    // bump refs
  247.         r = CTOB(flock);
  248.         }
  249.         break;
  250.     case ACTION_PARENT:        /*    Lock                Lock    */
  251.         {
  252.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  253.         FileLock *flock;
  254.  
  255.         if (gentry->ge_Parent) {
  256.             flock = MakeDosFileLock(gentry->ge_Parent, 1005);
  257.             MakeGEntry(gentry->ge_Parent, "", 0, 1005);    // bump refs
  258.             r = CTOB(flock);
  259.         } else {
  260.             r = 0;    // NO error code!
  261.         }
  262.         }
  263.         break;
  264.     case ACTION_EXAMINE_OBJECT: /*    Lock,Fib            Bool    */
  265.         {
  266.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  267.         FileInfoBlock *fib = BTOC(packet->dp_Arg2);
  268.  
  269.         if (gentry == &GRoot) {
  270.             clrmem(fib, sizeof(FileInfoBlock));
  271.             strcpy(fib->fib_FileName, DevName);
  272.             fib->fib_DirEntryType = ST_ROOT;
  273.             r = DOS_TRUE;
  274.         } else {
  275.             r = RoutePacket(packet);  // call underlying fs
  276.         }
  277.         if (r == DOS_TRUE)
  278.             FixFileInfo(fib);
  279.         }
  280.         break;
  281.     case ACTION_IS_FILESYSTEM:  /*    always return TRUE            */
  282.         r = DOS_TRUE;
  283.         break;
  284.     case ACTION_EXAMINE_NEXT:   /*    Lock,Fib            Bool    */
  285.         {
  286.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  287.         FileInfoBlock *fib = BTOC(packet->dp_Arg2);
  288.  
  289.         if (gentry == &GRoot)
  290.             r = -ERROR_NO_MORE_ENTRIES;
  291.         else
  292.             r = RoutePacket(packet);  // call underlying fs
  293.         if (r == DOS_TRUE)
  294.             FixFileInfo(fib);
  295.         }
  296.         break;
  297.     case ACTION_DELETE_OBJECT:  /*    Lock,Name            Bool    */
  298.         {
  299.         GEntry *gentry = BLockToGEntry(packet->dp_Arg1);
  300.         GEntry *gtmp;
  301.         short nameLen;
  302.         char *name = BNameToPtr(packet->dp_Arg2, &nameLen);
  303.  
  304.         if (gtmp = MakeGEntry(gentry, name, nameLen, 1005)) {
  305.             if (gtmp->ge_LCRefs != 1) {
  306.                 r = -ERROR_OBJECT_IN_USE;
  307.             } else {
  308.             r = 0;
  309.             }
  310.             FreeGEntry(gtmp, 1005);
  311.  
  312.             // XXX handle .Z extension
  313.  
  314.             if (r == 0)
  315.                 r = RoutePacket(packet);  // call underlying fs
  316.         } else {
  317.             r = -ERROR_OBJECT_NOT_FOUND;
  318.         }
  319.         }
  320.         break;
  321.     case ACTION_RENAME_OBJECT:  /*    SLock,SName,DLock,DName     Bool    */
  322.         /*
  323.          * Warning! does not handle case where source may be open
  324.          */
  325.  
  326.         r = RoutePacket(packet);
  327.         break;
  328.     case ACTION_MORE_CACHE:     /*    buffers             Bool    */
  329.         break;
  330.     case ACTION_SET_PROTECT:    /*    -,Lock,Name,Mask        Bool    */
  331.     case ACTION_SET_DATE:        /*    -,Lock,Name,cptr-datestamp  Bool    */
  332.         {
  333.         GEntry *gentry = BLockToGEntry(packet->dp_Arg2);
  334.  
  335.         if (gentry != &GRoot)
  336.             r = RoutePacket(packet);
  337.         }
  338.         break;
  339.     case ACTION_SET_COMMENT:    /*    -,Lock,Name,Comment        Bool    */
  340.         {
  341.         short len;
  342.         char *name = BNameToPtr(packet->dp_Arg3, &len);
  343.         short clen;
  344.         char *cname = BNameToPtr(packet->dp_Arg4, &clen);
  345.         GEntry *gentry = BLockToGEntry(packet->dp_Arg2);
  346.         GEntry *gen = MakeGEntry(gentry, name, len, SHARED_LOCK);
  347.  
  348.         if (gentry != &GRoot) {
  349.             SetCommentPacket(
  350.             gentry->ge_Lock,
  351.             name,
  352.             len,
  353.             cname,
  354.             clen,
  355.             gen
  356.             );
  357.         }
  358.         if (gen)
  359.             FreeGEntry(gen, 1005);
  360.         r = DOS_TRUE;
  361.         }
  362.         break;
  363.     case ACTION_CHANGE_MODE:    /*    CHANGE_*type,fh/lock,newmode   Bool */
  364.         r = -ERROR_ACTION_NOT_KNOWN;
  365.  
  366.         dbprintf(("Arg1 type %d\n", packet->dp_Arg1));
  367.         switch(packet->dp_Arg1) {
  368.         case CHANGE_FH:
  369.         GHandle *ghan = (GHandle *)packet->dp_Arg2;
  370.  
  371.         r = RoutePacket(packet);
  372.         if (r == 0) {
  373.             MakeGEntry(ghan->gh_GEntry, "", 0, packet->dp_Arg3);
  374.             FreeGEntry(ghan->gh_GEntry, ghan->gh_Mode);
  375.         }
  376.         break;
  377.         case CHANGE_LOCK:
  378.         /* XXX */
  379.         r = 0;
  380.         break;
  381.         }
  382.         break;
  383.     case ACTION_EXAMINE_ALL:    /*    lock,buf,len,ED_*type,ctl   contflag*/
  384.     case ACTION_DISK_INFO:        /*    InfoData            Bool    */
  385.     case ACTION_INFO:
  386.     case ACTION_FLUSH:        /*                    Bool    */
  387.     case ACTION_DISK_TYPE:
  388.     case ACTION_DISK_CHANGE:
  389.     case ACTION_SET_FILE_SIZE:  /*    fh,offset,seekmode        Bool    */
  390.  
  391.  
  392.     case ACTION_WRITE_PROTECT:
  393.     case ACTION_SAME_LOCK:        /*    Lock1,Lock2            LOCK_*  */
  394.     case ACTION_FH_FROM_LOCK:   /*    lock,openmode  (deref lock) Fh        */
  395.  
  396.  
  397.     case ACTION_COPY_DIR_FH:    /*    fh                   lock */
  398.     case ACTION_PARENT_FH:        /*    fh                   lock */
  399.     case ACTION_EVENT:
  400.     case ACTION_INHIBIT:        /*    Bool                Bool    */
  401.  
  402.     case ACTION_READ_RETURN:
  403.     case ACTION_WRITE_RETURN:
  404.     case ACTION_FORMAT:
  405.     case ACTION_MAKE_LINK:        /*    slock,slinkname,dlock/name,mode  Bool*/
  406.         /*
  407.          *    mode is LINK_SOFT or LINK_HARD
  408.          */
  409.  
  410.     case ACTION_READ_LINK:        /*    lock,cstr-name,pathbuf,bufsize    len */
  411.         /*
  412.          *    returned length is -1 on error, -2 if buffer too small
  413.          */
  414.  
  415.     case ACTION_LOCK_RECORD:    /*    fh,startpos,len,mode,to     Bool    */
  416.         /*
  417.          *    mode:  0=excl 1=excl/nbio 2=shared 3=shared/nbio
  418.          */
  419.  
  420.  
  421.     case ACTION_FREE_RECORD:    /*    fh,startpos,len         Bool    */
  422.     case ACTION_ADD_NOTIFY:
  423.     case ACTION_REMOVE_NOTIFY:
  424.     case ACTION_TIMER:
  425.     case ACTION_SCREEN_MODE:    /*    bool(-1=raw 0=cook)        OldState*/
  426.     case ACTION_WAIT_CHAR:        /*    timeout(ticks)            Bool    */
  427.     default:
  428.     def:
  429.         r = -ERROR_ACTION_NOT_KNOWN;
  430.         break;
  431.     }
  432.  
  433.     dbprintf(("return %08lx (%d)\n", r, r));
  434.  
  435.     if (packet) {
  436.         if (r < -1) {
  437.         packet->dp_Res1 = DOS_FALSE;
  438.         packet->dp_Res2 = -r;
  439.         } else {
  440.         packet->dp_Res1 = r;
  441.         packet->dp_Res2 = 0;
  442.         }
  443.         ReturnPacket(packet);
  444.     }
  445.     }
  446.     /*
  447.      *    not reached
  448.      */
  449. }
  450.  
  451. void
  452. myexit()
  453. {
  454.     UnInitialize();
  455. }
  456.  
  457. static const char Fubar[] = { "dee-ey-ey-el-el-oh-en" };
  458.